#include "MapZone.h"
#include "actor.h"

MapZone::MapZone():
    mNumCharacters(0), mNumMovingObjects(0)
{
}

void MapZone::insert(Actor *obj)
{
    int type = obj->getType();
    switch (type)
    {
        case OBJECT_CHARACTER:
        {
            if (mNumCharacters != mNumMovingObjects)
            {
                if (mNumMovingObjects != mActors.size())
                {
                    mActors.push_back(mActors[mNumMovingObjects]);
                    mActors[mNumMovingObjects] = mActors[mNumCharacters];
                }
                else
                {
                    mActors.push_back(mActors[mNumCharacters]);
                }
                mActors[mNumCharacters] = obj;
                ++mNumCharacters;
                ++mNumMovingObjects;
                break;
            }
            ++mNumCharacters;
        } // no break!
        case OBJECT_MONSTER:
        case OBJECT_NPC:
        {
            if (mNumMovingObjects != mActors.size())
            {
                mActors.push_back(mActors[mNumMovingObjects]);
                mActors[mNumMovingObjects] = obj;
                ++mNumMovingObjects;
                break;
            }
            ++mNumMovingObjects;
        } // no break!
        default:
        {
            mActors.push_back(obj);
        }
    }
}

void MapZone::remove(Actor *obj)
{
    std::vector< Actor * >::iterator i_beg = mActors.begin(), i, i_end;
    int type = obj->getType();
    switch (type)
    {
        case OBJECT_CHARACTER:
        {
            i = i_beg;
            i_end = mActors.begin() + mNumCharacters;
        } break;
        case OBJECT_MONSTER:
        case OBJECT_NPC:
        {
            i = mActors.begin() + mNumCharacters;
            i_end = mActors.begin() + mNumMovingObjects;
        } break;
        default:
        {
            i = mActors.begin() + mNumMovingObjects;
            i_end = mActors.end();
        }
    }
    i = std::find(i, i_end, obj);
    //leo assert(i != i_end);
    unsigned pos = i - i_beg;
    if (pos < mNumCharacters)
    {
        mActors[pos] = mActors[mNumCharacters - 1];
        pos = mNumCharacters - 1;
        --mNumCharacters;
    }
    if (pos < mNumMovingObjects)
    {
        mActors[pos] = mActors[mNumMovingObjects - 1];
        pos = mNumMovingObjects - 1;
        --mNumMovingObjects;
    }
    mActors[pos] = mActors[mActors.size() - 1];
    mActors.pop_back();
}

Actor *MapZone::getPointerToActorAtPos(const unsigned &pos)
{
    return mActors.at(pos);
}

unsigned MapZone::getNumActors()
{
    return mActors.size();
}

unsigned MapZone::getNumMovingObjects()
{
    return mNumMovingObjects;
}

unsigned MapZone::getNumCharacters()
{
    return mNumCharacters;
}
